package com.wonders.demo.config;

import com.wonders.demo.core.shiro.cache.RedisCacheManager;
import com.wonders.demo.core.shiro.realms.CustomRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;

/**
 * @author wonders
 */
@Configuration
public class ShiroConfig {
    /**
     * 创建shiroFilter
     *
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 指定ShiroFilter所绑定的SecurityManager
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);

        // 配置哪些页面需要ShiroFilter拦截。系统受限资源、系统公共资源
        HashMap<String, String> stringStringHashMap = new HashMap<>();
        //请求这个资源需要认证和授权
        // /**代表拦截项目中一切资源，anon和authc代表shiro中一个filter别名，详细内容看shirofilter文档
//        anon代表shiro中不需要走认证流程的请求
        stringStringHashMap.put("/register.jsp", "anon");
        stringStringHashMap.put("/sys/user/**", "anon");
        // 最后在配置需要认证的请求
//        authc代表shiro中需要走认证流程的请求
        stringStringHashMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(stringStringHashMap);

        //设置认证失败后跳转的页面
        shiroFilterFactoryBean.setLoginUrl("/login.jsp");

        return shiroFilterFactoryBean;
    }

    /**
     * 在web环境下要使用DefaultWebSecurityManager，而不是DefaultSecurityManager。
     * 原因是DefaultWebSecurityManager可以对session进行管理
     *
     * @param customRealm
     * @return
     */
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(CustomRealm customRealm) {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(customRealm);
        return defaultWebSecurityManager;
    }

    @Bean
    public CustomRealm customRealm() {
        CustomRealm customRealm = new CustomRealm();

        // 使用默认的EhCache缓存
//        customRealm.setCacheManager(new EhCacheManager());

        // 使用自己创建的RedisCacheManager
        customRealm.setCacheManager(new RedisCacheManager());
        // 开启全局realm缓存
        customRealm.setCachingEnabled(true);
        // 开启认证和授权的缓存（只有开启了全局缓存后才生效），默认的shiro只开启了授权缓存。
        customRealm.setAuthenticationCachingEnabled(true);
        customRealm.setAuthorizationCachingEnabled(true);

        // 给认证和授权的缓存起个名字，方便查找更新缓存
        customRealm.setAuthenticationCacheName("authenticationCache");
        customRealm.setAuthorizationCacheName("authorizationCache");

        return customRealm;
    }
}
